/**********************************************************************
*  Copyright (c) 2007 - Victor Jacobs - victor.jacobs@gmail.com
*
*  Permission is hereby granted, free of charge, to any person
*  obtaining a copy of this software and associated documentation
*  files (the "Software"), to deal in the Software without
*  restriction, including without limitation the rights to use,
*  copy, modify, merge, publish, distribute, sublicense, and/or sell
*  copies of the Software, and to permit persons to whom the
*  Software is furnished to do so, subject to the following
*  conditions:
*
*  The above copyright notice and this permission notice shall be
*  included in all copies or substantial portions of the Software.
*
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
*  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
*  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
*  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
*  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
*  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
*  OTHER DEALINGS IN THE SOFTWARE.
**********************************************************************/

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Drawing;
using Tao.OpenGl;
using Vj.MathLibrary;
using Vj.ShapeLibrary;

namespace Vj.BoidLibrary
{
    public class Boid : Shape
    {
        private List<Vector> vertexList;
        private List<Vector> normalList;

        private int xVertexCount;
        private int yVertexCount;

        public Boid(Color myColor)
        {
            this.Color = myColor;
            DefineShape(12, 12);
        }

        public void DefineShape(int height, int width)
        {
            xVertexCount = width;
            yVertexCount = height;

            vertexList = new List<Vector>();
            normalList = new List<Vector>();

            for (int i = 0; i <= xVertexCount; i++)
            {
                double lat0 = Math.PI * (-0.5 + (double)(i - 1) / xVertexCount);
                double z0 = Math.Sin(lat0);
                double zr0 = Math.Cos(lat0);

                double lat1 = Math.PI * (-0.5 + (double)i / xVertexCount);
                double z1 = Math.Sin(lat1);
                double zr1 = Math.Cos(lat1);

                for (int j = 0; j <= yVertexCount; j++)
                {
                    double lng = 2 * Math.PI * (double)(j - 1) / yVertexCount;
                    double x = Math.Cos(lng);
                    double y = Math.Sin(lng);

                    vertexList.Add(new Vector((x * zr0), (y * zr0), z0));
                    normalList.Add(new Vector((x * zr0), (y * zr0), z0));
                    vertexList.Add(new Vector((x * zr1), (y * zr1), z1));
                    normalList.Add(new Vector((x * zr1), (y * zr1), z1));
                }
            }
        }

        public override void Draw()
        {
            float[] mat_diffuse = { (float)Color.R, (float)Color.G, (float)Color.B, 1.0f };
            float[] mat_specular ={ (float)Color.R, (float)Color.G, (float)Color.B, 1.0f };
            float[] mat_ambient = { (float)Color.R, (float)Color.G, (float)Color.B, 1.0f };

            Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, mat_specular);
            Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, mat_diffuse);
            Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, mat_ambient);

            Gl.glPushMatrix();
            Gl.glTranslated(Position[0], Position[1], Position[2]);
            Gl.glRotated(RotationAngle, RotationVector[0], RotationVector[1], RotationVector[2]);
            //Gl.glScalef(0.1f, 0.1f, 0.1f);

            //int k = 0;
            //for (int i = 0; i <= xVertexCount; i++)
            //{
            //    Gl.glBegin(Gl.GL_QUAD_STRIP);
            //    for (int j = 0; j <= yVertexCount; j++)
            //    {
            //        Gl.glNormal3d(normalList[k].X, normalList[k].Y, normalList[k].Z);
            //        Gl.glVertex3d(vertexList[k].X, vertexList[k].Y, vertexList[k].Z);
            //        Gl.glNormal3d(normalList[k + 1].X, normalList[k + 1].Y, normalList[k + 1].Z);
            //        Gl.glVertex3d(vertexList[k + 1].X, vertexList[k + 1].Y, vertexList[k + 1].Z);

            //        k = k + 2;
            //    }
            //    Gl.glEnd();
            //}

            Gl.glBegin(Gl.GL_LINE_STRIP);
            
            Vector normalizedVelocity = Vector.Normalize(this.Velocity);

            Gl.glVertex3d(-0.25, -0.25, -0.25);
            Gl.glVertex3d(1.0 * normalizedVelocity.X, 1.0 * normalizedVelocity.Y, 1.0 * normalizedVelocity.Z);
            Gl.glVertex3d(0.25, 0.25, 0.25);
            Gl.glVertex3d(-0.25, -0.25, -0.25);
            Gl.glEnd();
            
            
            Gl.glPopMatrix();
        }


        public override string ToString()
        {
            string output = " ";


            output += "Location: " + this.Position;
            output += "\r\n";
            output += "Velocity: " + this.Velocity;
            output += "\r\n";
            return output;
        }
    }

}
